package com.ruoyi.syf.handler.task.strategy;

import com.ruoyi.common.constant.TimeUnit;
import com.ruoyi.common.utils.CronUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MyCalendar;
import com.ruoyi.syf.common.constant.TaskType;
import com.ruoyi.syf.handler.task.TaskStrategy;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;

/**
 * 隐患排查定时任务策略-自定义2（强指定开始时间类型）(目前不使用)
 *
 * @author yr
 * @date 2024-07-31
 */
@Service
public class AppointTaskStrategy implements TaskStrategy {
    @Override
    public String getTaskType() {
        return TaskType.APPOINT;
    }

    @Override
    public String toCronExpression(int num, String timeUnit, Date startTime) throws IllegalAccessException {
        MyCalendar calendar = new MyCalendar(startTime);
        return CronUtil.toCronExpressionAppoint(calendar, num, timeUnit, startTime);
    }

    /**
     * 例：周期单位为小时，任务开始时间为yyyy-MM-dd 10:mm:ss，
     * 如果计算得出的排查任务开始时间的小时位上的数小于10则将计算得出的排查任务开始时间的小时位设为10
     */
    @Override
    public Date getNextBeginTime(Date date, Date startTime, Integer cycle, String cycleUnit) throws IllegalAccessException {
        Date beginDate = DateUtils.getNextDateByCycle(date, cycle, cycleUnit);
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(beginDate);
        int year1 = calendar1.get(Calendar.YEAR);
        int month1 = calendar1.get(Calendar.MONTH);
        int week1 = calendar1.get(Calendar.WEEK_OF_YEAR);
        int day1 = calendar1.get(Calendar.DAY_OF_MONTH);
        int hour1 = calendar1.get(Calendar.HOUR_OF_DAY);
        int minute1 = calendar1.get(Calendar.MINUTE);
        int second1 = calendar1.get(Calendar.SECOND);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(startTime);
        int year2 = calendar2.get(Calendar.YEAR);
        int week2 = calendar2.get(Calendar.WEEK_OF_YEAR);
        int month2 = calendar2.get(Calendar.MONTH);
        int day2 = calendar2.get(Calendar.DAY_OF_MONTH);
        int hour2 = calendar2.get(Calendar.HOUR_OF_DAY);
        int minute2 = calendar2.get(Calendar.MINUTE);
        int second2 = calendar2.get(Calendar.SECOND);
        TimeUnit timeUnit = TimeUnit.getByCode(cycleUnit);
        switch (timeUnit) {
            case SECOND:
                if (second1 < second2 || (second1 - second2) % cycle != 0) {
                    calendar1.set(Calendar.SECOND, second2);
                }
                break;
            case MIN:
                if (minute1 < minute2 || (minute1 - minute2) % cycle != 0) {
                    calendar1.set(Calendar.MINUTE, minute2);
                }
                break;
            case HOUR:
                if (hour1 < hour2 || (hour1 - hour2) % cycle != 0) {
                    calendar1.set(Calendar.HOUR_OF_DAY, hour2);
                }
                break;
            case DAY:
                if (day1 < day2 || (day1 - day2) % cycle != 0) {
                    calendar1.set(Calendar.DAY_OF_MONTH, day2);
                }
                break;
            case WEEK:
                if (week1 < week2 || (week1 - week2) % cycle != 0) {
                    calendar1.set(Calendar.WEEK_OF_YEAR, week2);
                }
                break;
            case MOON:
                if (month1 < month2 || (month1 - month2) % cycle != 0) {
                    calendar1.set(Calendar.MONTH, month2);
                }
                break;
            case YEAR:
                if (year1 < year2) {
                    calendar1.set(Calendar.YEAR, year2);
                }
                break;
        }
        return calendar1.getTime();
    }

    @Override
    public Date getLastBeginTime(Date startTime, Integer cycle, String cycleUnit) {
        return null;
    }

    @Override
    public Date getRecentBeginTime(Date startTime, Integer cycle, String cycleUnit) throws IllegalAccessException {
        Date timeByCycle = getTimeByCycle(startTime, cycle, cycleUnit, System.currentTimeMillis());
        return getNextBeginTime(timeByCycle, startTime, cycle, cycleUnit);
    }

    private Date getTimeByCycle(Date startTime, Integer cycle, String cycleUnit, long time) throws IllegalAccessException {
        Date dateByCycle = DateUtils.getNextDateByCycle(startTime, cycle, cycleUnit);
        if (dateByCycle.getTime() <= time) {
            return getTimeByCycle(dateByCycle, cycle, cycleUnit, time);
        }
        return startTime;
    }
}
